package com.uwlaser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.modules.system.domain.DictDetail;
import com.uwlaser.modules.system.service.dto.DictDetailDto;
import com.uwlaser.modules.system.service.mapper.DictDetailMapper;
import com.uwlaser.utils.DateUtil;
import com.uwlaser.utils.StringUtils;
import com.uwlaser.utils.enums.DictTypeEnum;
import com.uwlaser.utils.enums.DictValueEnum;
import lombok.AllArgsConstructor;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.utils.ConvertUtil;
import com.uwlaser.utils.PageUtil;
import com.uwlaser.domain.DeviceStatus;
import com.uwlaser.service.DeviceStatusService;
import com.uwlaser.service.dto.DeviceStatusDto;
import com.uwlaser.service.dto.DeviceStatusQueryParam;
import com.uwlaser.service.mapper.DeviceStatusMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
//import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
//import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Pageable;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = DeviceStatusService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeviceStatusServiceImpl extends CommonServiceImpl<DeviceStatusMapper, DeviceStatus> implements DeviceStatusService {

    // private final RedisUtils redisUtils;
    private final DeviceStatusMapper deviceStatusMapper;

    private final DictDetailMapper dictDetailMapper;


    @Override
    public PageInfo<DeviceStatusDto> queryAll(DeviceStatusQueryParam query, Pageable pageable) {
        IPage<DeviceStatus> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<DeviceStatus> page = deviceStatusMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, DeviceStatusDto.class);
    }

    @Override
    public List<DeviceStatusDto> queryAll(DeviceStatusQueryParam query){
        return ConvertUtil.convertList(deviceStatusMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), DeviceStatusDto.class);
    }

    @Override
    public DeviceStatus getById(Integer id) {
        return deviceStatusMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public DeviceStatusDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), DeviceStatusDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DeviceStatusDto resources) {
        DeviceStatus entity = ConvertUtil.convert(resources, DeviceStatus.class);
        return deviceStatusMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(DeviceStatusDto resources){
        DeviceStatus entity = ConvertUtil.convert(resources, DeviceStatus.class);
        int ret = deviceStatusMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<Integer> ids){
        // delCaches(ids);
        return deviceStatusMapper.deleteBatchIds(ids);
    }


    @Override
    public Map<String, Object> getTrend(DeviceStatusQueryParam query) {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//注意月份是MM

        String trendDay = query.getTrendDay();
        String trendMonth = query.getTrendMonth();
        String startHour = " 00:00:00";
        String endHour = " 23:59:59";
        String startTime = "";
        String endTime = "";

        if(!StringUtils.isEmpty(trendDay)){
            //日
            startTime = trendDay;
            endTime = trendDay;
        }else if (!StringUtils.isEmpty(trendMonth)){
            //月
            String[] split = trendMonth.split("-");
            startTime = DateUtil.getMonthFirstDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
            endTime = DateUtil.getMonthLastDay(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
        }else {
            trendDay = DateUtil.getCurrentDate("yyyy-MM-dd");
            startTime = trendDay;
            endTime = trendDay;
        }

        //返回结果
        Map<String, Object> resMap = new HashMap<>();

        //获取设备状态列表
        List<DictDetailDto> dictDetails = dictDetailMapper.getDictDetailsByDictName(DictTypeEnum.DEVICE_STATUS.getName());
        if(dictDetails == null || dictDetails.size() == 0){
            throw new RuntimeException("设备状态字典【"+DictTypeEnum.DEVICE_STATUS.getName()+"】为空！");
        }
        //设置标题
        List<String> title = dictDetails.stream().map(DictDetailDto::getLabel).collect(Collectors.toList());
        resMap.put("title",title);

        try {
            //日期+时间
            startTime = startTime + startHour;
            endTime = endTime + endHour;
            //字符串日期转Date对象
            Date startDate = simpleDateFormat.parse(startTime);
            Date endDate = simpleDateFormat.parse(endTime);
            //设置时间条件
            query.setCreateTime(Arrays.asList(startDate,endDate));

            //根据条件查询设备状态
            List<DeviceStatusDto> list = queryAll(query);

            //排序
            List<DeviceStatusDto> sortList = new ArrayList<>();

            //计算日期
            for (int i = 0; i < list.size(); i++) {
                DeviceStatusDto statusRecord = list.get(i);
                sortList.add(statusRecord);
                if( i < list.size() -1 ){
                    Date current = statusRecord.getCreateTime();
                    int hours = current.getHours();
                    Date next = list.get(i + 1).getCreateTime();
                    int nexthHours = next.getHours();
                    if(hours != nexthHours){
                        for (int h = hours; h < nexthHours; h++) {
                            //小时结束
                            DeviceStatusDto currentEnd = new DeviceStatusDto();
                            currentEnd.setDeviceStatus(statusRecord.getDeviceStatus());
                            String strHours = h < 10 ? "0" + h : "" + h;
                            String dateTime = trendDay + " " + strHours + ":59:59";
                            currentEnd.setCreateTime(simpleDateFormat.parse(dateTime));
                            sortList.add(currentEnd);

                            //下个小时开始
                            int h1 = h + 1 ;
                            DeviceStatusDto nextStart = new DeviceStatusDto();
                            nextStart.setDeviceStatus(statusRecord.getDeviceStatus());
                            String strHours2 = h1 < 10 ? "0" + h1 : "" + h1;
                            String dateTime2 = trendDay + " " + strHours2 + ":00:00";
                            nextStart.setCreateTime(simpleDateFormat.parse(dateTime2));
                            sortList.add(nextStart);
                        }
                    }
                }
            }

            // (31日)
            if(!StringUtils.isEmpty(trendMonth)){
                //设置默认值
                dictDetails.forEach(item -> {
                    HashMap<String, Integer> statusMap = new LinkedHashMap<>();
                    for (int i = 1; i <= 31 ; i ++){
                        String mapKey = "";
                        if(i < 10){
                            mapKey = "0" + i;
                        }else{
                            mapKey =  "" + i;
                        }
                        statusMap.put(mapKey,0);
                    }
                    resMap.put(item.getValue(),statusMap);
                });

                //计算时长
                for (int i = 0; i < sortList.size(); i++) {
                    if( i < sortList.size() -1 ){
                        DeviceStatusDto statusRecord = sortList.get(i);
                        DeviceStatusDto nextStatusRecord = sortList.get(i + 1);
                        Date ctime = statusRecord.getCreateTime();
                        Date ntime = nextStatusRecord.getCreateTime();
                        int l =  (int) (ntime.getTime() - ctime.getTime() ) / 1000 / 60;

                        String key =  ctime.getHours() < 10 ? "0" + ctime.getHours() : "" + ctime.getHours();

                        //获取状态对应的map
                        Map<String,Integer> statusMap = (Map<String,Integer>) resMap.get(statusRecord.getDeviceStatus());

                        statusMap.put(key,statusMap.get(key) + l);

                        resMap.put(statusRecord.getDeviceStatus(),statusMap);
                    }
                }

                //(24小时)
            }else{
                //设置默认值
                dictDetails.forEach(item -> {
                    HashMap<String, Integer> statusMap = new LinkedHashMap<>();
                    for (int i = 0; i <= 23 ; i ++){
                        String mapKey = "";
                        if(i < 10){
                            mapKey = "0" + i;
                        }else{
                            mapKey =  "" + i;
                        }
                        statusMap.put(mapKey,0);
                    }
                    resMap.put(item.getValue(),statusMap);
                });

                //计算
                for (int i = 0; i < sortList.size(); i++) {
                    if( i < sortList.size() -1 ){
                        DeviceStatusDto statusRecord = sortList.get(i);
                        DeviceStatusDto nextStatusRecord = sortList.get(i + 1);
                        Date ctime = statusRecord.getCreateTime();
                        Date ntime = nextStatusRecord.getCreateTime();
                        int l =  (int) (ntime.getTime() - ctime.getTime() ) / 1000 / 60;

                        String key =  ctime.getHours() < 10 ? "0" + ctime.getHours() : "" + ctime.getHours();

                        //获取状态对应的map
                        Map<String,Integer> statusMap = (Map<String,Integer>) resMap.get(statusRecord.getDeviceStatus());

                        statusMap.put(key,statusMap.get(key) + l);

                        resMap.put(statusRecord.getDeviceStatus(),statusMap);
                    }
                }
            }
            //获取第一条数据线，设置图表X轴数据
            Map<String, Integer> firstData = (Map<String, Integer>) resMap.get(dictDetails.get(0).getValue());
            List<String> collect = firstData.keySet().stream().sorted().collect(Collectors.toList());
            resMap.put("xAxis",collect);

            return resMap;
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Integer id){
        Set<Integer> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<DeviceStatusDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (DeviceStatusDto deviceStatus : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("设备编码", deviceStatus.getDeviceCode());
              map.put("设备名称", deviceStatus.getDeviceName());
              map.put("产线编码", deviceStatus.getLineCode());
              map.put("工段编码", deviceStatus.getSectionCode());
              map.put("工位编码", deviceStatus.getStationCode());
              map.put("设备状态", deviceStatus.getDeviceStatus());
              map.put("耗时（分）", deviceStatus.getTripTime());
              map.put("创建人", deviceStatus.getCreateBy());
              map.put("创建时间", deviceStatus.getCreateTime());
              map.put("更新人", deviceStatus.getUpdateBy());
              map.put("更新时间", deviceStatus.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/
}
